#pragma once

#include <iostream>
#include <set>
#include <sys/epoll.h>
#include "LogMessage.hpp"

const int defaultsize = 128;

class Epoller
{
public:
    Epoller()
    {
        epfd = epoll_create(defaultsize);
        if (epfd < 0)
        {
            lg.LogMessage(Error, "create epoll error");
            exit(1);
        }
        lg.LogMessage(Normal, "create epoll success, epfd: %d", epfd);
    }

    ~Epoller()
    {
        close(epfd);
    }

    void AddEpoll(int fd, uint32_t event)
    {
        struct epoll_event evt;
        evt.events = 0;
        evt.events |= event;
        evt.data.fd = fd;
        epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &evt);

        sockset.insert(fd);
    }

    void ModEpoll(int fd, uint32_t event)
    {
        struct epoll_event evt;
        evt.events = 0;
        evt.events |= event;
        evt.data.fd = fd;
        epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &evt);
    }

    void DelEpoll(int fd)
    {
        epoll_ctl(epfd, EPOLL_CTL_DEL, fd, nullptr);
        sockset.erase(fd);
    }

    int WaitEpoll(epoll_event* events, size_t eventsize, int timeout)
    {
        int n = epoll_wait(epfd, events, eventsize, timeout);
        return n;
    }

    void PrintAllSockfd()
    {
        std::cout << "All epoll sockfd: ";
        for (auto e : sockset)
        {
            std::cout << e << " ";
        }
        std::cout << std::endl;
    }

private:
    int epfd;
    std::set<int> sockset;
};